home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
hardware
/
cpu115
/
cpuspeed.asm
< prev
next >
Wrap
Assembly Source File
|
1995-02-27
|
6KB
|
330 lines
; -----------------------------------------------------------------------------
; CPUSPEED.ASM CPU speed measurement routine Version 1.15
;
; Too-Much-In-One-So-Don't-Get-Lost(tm) CPU/FPU feature detection library
;
; Copyright(c) 1993-95 by B-coolWare. Written by Bobby Z.
; -----------------------------------------------------------------------------
INCLUDE HEADER.ASH
.DATA
EXTRN CPUFix: DWORD ; CPU Type speed fix constant
EXTRN Shift : WORD ; current loop length
.CODE
ifndef __use_386__
ifdef __use_286__
.286
endif
else
__use_286__ equ 1
.386
endif
PUBLIC Speed
_bpes equ <byte ptr es:>
_wp equ <word ptr>
clr macro reg
sub reg,reg
endm
IsUnderWin proc near
mov ax,1600h
int 2Fh
or al,al
jz @@nowin
cmp al,80h
jz @@nowin
stc
ret
@@nowin:
clc
ret
endp
WinStartCritical proc near
push ax
call IsUnderWin
jnc @@Q
mov ax,1681h
int 2Fh
@@Q:
pop ax
ret
endp
WinEndCritical proc near
push ax
call IsUnderWin
jnc @@Q
mov ax,1682h
int 2Fh
@@Q:
pop ax
ret
endp
isUnderDV proc near
mov ax,2B01h
push cx dx
mov cx,4445h
mov dx,5351h
int 21h
pop dx cx
cmp al,0FFh
jz @@noDV
stc
ret
@@noDV:
clc
ret
endp
DVStartCritical proc near
push ax
call isUnderDV
jnc @@Q
mov ax,101Bh
int 15h
@@Q:
pop ax
ret
endp
DVEndCritical proc near
push ax
call isUnderDV
jnc @@Q
mov ax,101Ch
int 15h
@@Q:
pop ax
ret
endp
; -----------------------------------------------------------------------
; Speed modifies CPUFix and Shift and returns value which should b used
; as follows:
;
; CPUSpeed_In_MHz := (((CPUFix*Shift)/Speed)+5)/10;
;
; This formulae is taken from Norton SysInfo unchanged. I've no idea why
; computations done this way, but it works ok.
; I dinna insert floating point here, but to use with assembler you'll have to
; do so.
; Shift should be converted to DWORD prior to multiplication.
; Resulting value may be rounded to nearest integer, or may be left unchanged
; if you want exact CLK frequency value.
; function Speed( CPUid : Byte ) : Word;
; unsigned int Speed( unsigned short CPUid );
; CPUid is value from 0 to 13h identifying processor we're running on
; 8088 = 00h
; 8086 = 01h
; V20 = 02h
; V30 = 03h
; 188 = 04h
; 186 = 05h
; 286 = 06h
; 386sx = 07h
; 386dx = 08h
; 386sl = 09h
; 486sx = 0Ah
; 486dx = 0Bh
; 486slc = 0Ch
; Cx486 = 0Dh
; P5 = 0Eh
; CxM1 = 0Fh
; Am386sx= 10h
; Am386dx= 11h
; UMC U5s= 12h
; UMC U5d= 13h -??? I don't know if this CPU really exists...
; It is lower byte of the result of CPU_Type routine defined in CPU_TYPE.ASH
; or CPU_HL.ASM.
MaxCPUid equ 14h ; change this if you added new CPU types
Speed PROC
ARG CPUid:BYTE
ifdef __DPMI__
mov ax,dpmiCreateCodeAlias
mov bx,cs
int 31h
mov es,ax
else
push cs
pop es
endif
cmp CPUid,MaxCPUid ; checking if we know this CPU
jbe @@okcpu
mov CPUid,MaxCPUid ; fixing CPU id - let's assume it's P5 or
; better :)
@@okcpu:
mov cx,2
mov _bpes[Indic],0
call WinStartCritical
call DVStartCritical
@@1:
mov Shift,cx
call Speed_Test
cmp ax,1000h
jnb @@2
mov cx,Shift
shl cx,1
shl cx,1
shl cx,1
jmp @@1
@@2:
push ax
mov cx,Shift
mov _bpes[Indic],1
call Speed_Test
call WinEndCritical
call DVEndCritical
pop dx
sub dx,ax
xchg ax,dx
ifdef __use_386__
movzx bx,CPUid
else
mov bl,CPUid
clr bh
endif
ifdef __use_286__
shl bx,2
else
shl bx,1
shl bx,1
endif
ifdef __use_386__
mov edx,es:CPUFixes[bx]
mov CPUFix,edx
else
mov dx,_wp es:CPUFixes[bx]
mov _wp CPUFix,dx
mov dx,_wp es:CPUFixes[2][bx]
mov _wp CPUFix[2],dx
endif
ifdef __DPMI__
push ax bx
mov ax,dpmiFreeLDTDesc
mov bx,es
int 31h
pop bx ax
endif
ret
ENDP
Speed_Test PROC NEAR
; returns number of tick-tacks spent performing known instruction?
; or difference between time taken by plain group of similar instructions and
; time taken by loop of that instructions? I dinna find out what exactly it
; does, but it works - what else do i (and u) need?
PUSH SI DI
CLR DX,DX
MOV SI,0AAAAH
MOV BX,05555H
IN AL,61h
JMP $+2
AND AL,0FCH
OUT 61h,AL
JMP $+2
MOV AL,0B4h
OUT 43h,AL
JMP $+2
CLR AL
OUT 42h,AL
JMP $+2
OUT 42h,AL
JMP $+2
IN AL,61h
MOV DI,AX
OR AL,01
CMP _BPES[INDIC],0
JZ @@1
JMP @@2
@@1:
CLI
OUT 61h,AL
@@3:
Sprite equ <8Bh, 0C6h, 0F7h, 0F3h>
; MOV AX,SI
; DIV BX
db 101 dup(Sprite)
DEC CX
JZ @@4
JMP @@3
@@2:
CLI
OUT 61h,AL
NOP ; well, maybe this is the right place for
; NOP, so i left it here. Try to kill it and
; see what will happen...
@@5:
db Sprite
DEC CX
JZ @@4
JMP @@5
@@4:
MOV AX,DI
OUT 61h,AL
JMP $+2
STI
IN AL,42h
JMP $+2
XCHG AH,AL
IN AL,42h
JMP $+2
XCHG AH,AL
NEG AX
PUSH AX
IN AL,61h
JMP $+2
AND AL,0FDh
OUT 61h,AL
POP AX DI SI
RET
ENDP
Indic db ?
CPUFixes:
; For on different processors the same instruction takes different number of
; CPU clocks, we should adjust absolute timer value using our knowledge of
; known CPU's timings.
dd 2AD26h ; 8088
dd 2AD26h ; 8086
dd 0E90Bh ; V20
dd 0DFB9h ; V30
dd 0BA6Fh ; 188
dd 0BA6Fh ; 186
dd 06FDCh ; 286
dd 07486h ; 386sx
dd 07486h ; 386dx
dd 07486h ; 386sl
dd 07486h ; 486sx
dd 07486h ; 486dx
dd 0668Ah ; Cx486slc
dd 0668Ah ; Cx486sx/dx/dlc
dd 0792Fh ; Pentium
dd 0668Ah ; CxM1
dd 0792Fh ; P24D
dd 07415h ; Am386sx
dd 07415h ; Am386dx
dd 0792Fh ; UMC U5-S
dd 0792Fh ; UMC U5-D
END